package com.alibaba.cloud.base.business.dict.service.impl;

import com.alibaba.cloud.base.business.dict.dao.BasDictMapper;
import com.alibaba.cloud.base.business.dict.domain.BasDict;
import com.alibaba.cloud.base.business.dict.service.BasDictService;
import com.alibaba.cloud.base.constant.BaseConstant;
import com.alibaba.fastjson.JSON;
import com.alibaba.framework.exception.BusinessException;
import com.alibaba.framework.wrapper.RedisWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class BasDictServiceImpl implements BasDictService {

    @Autowired
    private BasDictMapper basDictMapper;

    @Autowired
    private RedisWrapper<String, Object> redisWrapper;

    @Override
    public List<BasDict> getAll() {

        QueryWrapper<BasDict> wrapper = new QueryWrapper<>();
        List<BasDict> basDictList = basDictMapper.selectList(wrapper);

        return basDictList;
    }

    @Override
    public List<BasDict> getDictByType(String dictType) {
        String dictTypeKey = BaseConstant.BASE_DICT_KEY + dictType;
        if (redisWrapper.hasKey(dictTypeKey)) {
            Object value = redisWrapper.getValue(dictTypeKey);
            List<BasDict> basDictList = JSON.parseArray(value.toString(), BasDict.class);
            return basDictList;
        }

        QueryWrapper<BasDict> wrapper = new QueryWrapper<>();
        wrapper.eq("dict_type", dictType);
        List<BasDict> basDictList = basDictMapper.selectList(wrapper);
        redisWrapper.putValueWithExpireTime(dictTypeKey, JSON.toJSONString(basDictList), BaseConstant.EXPIRE_TIME, TimeUnit.SECONDS);
        return basDictList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(BasDict basDict) {
        validateDict(basDict.getDictName());
        basDict.setCreateTime(new Date());
        basDictMapper.insert(basDict);
        redisWrapper.delWithKey(BaseConstant.BASE_DICT_KEY + basDict.getDictType());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(BasDict basDict) {
        validateDict(basDict.getDictName());
        basDict.setUpdateTime(new Date());
        basDictMapper.updateById(basDict);
        redisWrapper.delWithKey(BaseConstant.BASE_DICT_KEY + basDict.getDictType());
    }

    /**
     * @descript 校验字典名称是否重复
     * @author focus
     * @date 2025/10/27
     */
    private void validateDict(String dictName) {
        QueryWrapper<BasDict> wrapper = new QueryWrapper<>();
        wrapper.eq("dict_name", dictName);
        BasDict dict = basDictMapper.selectOne(wrapper);
        if (!Objects.isNull(dict)) {
            throw new BusinessException("字典项目已存在");
        }
    }
}
